{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "outputs": [],
   "source": [
    "import math\n",
    "import torch\n",
    "from torch import nn\n",
    "import matplotlib.pyplot as plt\n",
    "from IPython.core.interactiveshell import InteractiveShell\n",
    "InteractiveShell.ast_node_interactivity = 'all'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "origin_pos": 0,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "<div class=\"jumbotron\">\n",
    "    <p class=\"display-1 h1\">自注意力和位置编码</p>\n",
    "    <hr class=\"my-4\">\n",
    "    <p>主讲：李岩</p>\n",
    "    <p>管理学院</p>\n",
    "    <p>liyan@cumtb.edu.cn</p>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## 什么是自注意力？\n",
    "\n",
    "### 传统序列编码方法\n",
    "\n",
    "**深度学习中常用的序列编码方法**：\n",
    "- **卷积神经网络（CNN）**：使用卷积核扫描序列\n",
    "- **循环神经网络（RNN）**：逐个处理序列元素\n",
    "\n",
    "**这些方法的共同特点**：\n",
    "- 需要逐步处理序列\n",
    "- 难以并行计算\n",
    "- 长距离依赖建模困难\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 自注意力的核心思想\n",
    "\n",
    "**关键观察**：\n",
    "- 有了注意力机制后，可以将词元序列输入注意力池化\n",
    "- **同一组词元**同时充当**查询、键和值**\n",
    "\n",
    "**定义**：\n",
    "- **自注意力（Self-Attention）**：查询、键和值都来自同一组输入\n",
    "- 也被称为**内部注意力（Intra-Attention）**\n",
    "\n",
    "**特点**：\n",
    "- 每个查询关注**所有**键值对\n",
    "- 生成注意力输出\n",
    "- 可以并行计算\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 自注意力 vs 普通注意力\n",
    "\n",
    "**关键区别**：\n",
    "\n",
    "| 特性 | 普通注意力 | 自注意力 |\n",
    "|------|-----------|---------|\n",
    "| **查询来源** | 解码器 | 同一序列 |\n",
    "| **键值来源** | 编码器 | 同一序列 |\n",
    "| **应用场景** | 序列到序列任务 | 序列内部关系建模 |\n",
    "| **典型应用** | 机器翻译 | BERT、GPT |\n",
    "\n",
    "**类比**：\n",
    "- 普通注意力：像\"翻译时看原文\"（跨序列）\n",
    "- 自注意力：像\"阅读时理解句子内部关系\"（序列内部）\n",
    "\n",
    "**实际例子**：\n",
    "\n",
    "**普通注意力（机器翻译）**：\n",
    "- 输入：\"I love deep learning\"\n",
    "- 查询：解码器当前状态（想生成\"我\"）\n",
    "- 键值：编码器输出（\"I\", \"love\", \"deep\", \"learning\"）\n",
    "- 作用：生成\"我\"时关注\"I\"\n",
    "\n",
    "**自注意力（BERT）**：\n",
    "- 输入：\"The cat sat on the mat\"\n",
    "- 查询、键、值：都来自这个句子\n",
    "- 作用：理解\"cat\"与\"sat\"的关系（主谓关系）\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 自注意力的计算公式\n",
    "\n",
    "**核心公式**：\n",
    "$$\\mathbf{y}_i = f(\\mathbf{x}_i, (\\mathbf{x}_1, \\mathbf{x}_1), \\ldots, (\\mathbf{x}_n, \\mathbf{x}_n)) \\in \\mathbb{R}^d$$\n",
    "\n",
    "**符号说明**：\n",
    "- $\\mathbf{x}_i$：第$i$个词元（作为查询）\n",
    "- $(\\mathbf{x}_1, \\mathbf{x}_1), \\ldots, (\\mathbf{x}_n, \\mathbf{x}_n)$：所有词元作为键值对\n",
    "- $f$：注意力汇聚函数（如缩放点积注意力）\n",
    "\n",
    "**关键特点**：\n",
    "- 查询是$\\mathbf{x}_i$\n",
    "- 键和值都是$\\mathbf{x}_1, \\ldots, \\mathbf{x}_n$\n",
    "- **所有都来自同一输入序列**\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 自注意力的计算过程\n",
    "\n",
    "**步骤**：\n",
    "\n",
    "1. **生成查询、键、值**：\n",
    "   - 查询：$\\mathbf{Q} = \\mathbf{X}\\mathbf{W}_q$（$\\mathbf{X}$是输入矩阵）\n",
    "   - 键：$\\mathbf{K} = \\mathbf{X}\\mathbf{W}_k$\n",
    "   - 值：$\\mathbf{V} = \\mathbf{X}\\mathbf{W}_v$\n",
    "\n",
    "2. **计算注意力分数**：\n",
    "   - $\\mathbf{S} = \\mathbf{Q}\\mathbf{K}^T / \\sqrt{d}$\n",
    "\n",
    "3. **应用softmax**：\n",
    "   - $\\mathbf{A} = \\text{softmax}(\\mathbf{S})$\n",
    "\n",
    "4. **加权求和**：\n",
    "   - $\\mathbf{Y} = \\mathbf{A}\\mathbf{V}$\n",
    "\n",
    "**结果**：\n",
    "- 输出形状：`(batch_size, num_steps, d)`\n",
    "- 与输入形状相同\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 使用多头注意力实现自注意力\n",
    "\n",
    "**实现方式**：\n",
    "- 使用`MultiHeadAttention`类\n",
    "- 将查询、键、值都设置为相同的输入\n",
    "\n",
    "**参数设置**：\n",
    "- `num_hiddens = 100`：隐状态维度\n",
    "- `num_heads = 5`：注意力头数\n",
    "\n",
    "**注意**：\n",
    "- 输入形状：`(batch_size, num_steps, num_hiddens)`\n",
    "- 输出形状：`(batch_size, num_steps, num_hiddens)`\n",
    "- 形状保持不变\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "outputs": [],
   "source": [
    "def sequence_mask(X, valid_len, value=0):\n",
    "    \"\"\"在序列中屏蔽不相关的项\"\"\"\n",
    "    maxlen = X.size(1)\n",
    "    mask = torch.arange((maxlen), dtype=torch.float32,\n",
    "                        device=X.device)[None, :] < valid_len[:, None]\n",
    "    X[~mask] = value\n",
    "    return X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "outputs": [],
   "source": [
    "def masked_softmax(X, valid_lens):\n",
    "    \"\"\"通过在最后一个轴上掩蔽元素来执行softmax操作\"\"\"\n",
    "    # X:3D张量，valid_lens:1D或2D张量\n",
    "    if valid_lens is None:\n",
    "        return nn.functional.softmax(X, dim=-1)\n",
    "    else:\n",
    "        shape = X.shape\n",
    "        if valid_lens.dim() == 1:\n",
    "            valid_lens = torch.repeat_interleave(valid_lens, shape[1])\n",
    "        else:\n",
    "            valid_lens = valid_lens.reshape(-1)\n",
    "        # 最后一轴上被掩蔽的元素使用一个非常大的负值替换，从而其softmax输出为0\n",
    "        X = sequence_mask(X.reshape(-1, shape[-1]), valid_lens,value=-1e6)\n",
    "        return nn.functional.softmax(X.reshape(shape), dim=-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "outputs": [],
   "source": [
    "class DotProductAttention(nn.Module):\n",
    "    \"\"\"缩放点积注意力\"\"\"\n",
    "    def __init__(self, dropout, **kwargs):\n",
    "        super(DotProductAttention, self).__init__(**kwargs)\n",
    "        self.dropout = nn.Dropout(dropout)\n",
    "\n",
    "    # queries的形状：(batch_size，查询的个数，d)\n",
    "    # keys的形状：(batch_size，“键－值”对的个数，d)\n",
    "    # values的形状：(batch_size，“键－值”对的个数，值的维度)\n",
    "    # valid_lens的形状:(batch_size，)或者(batch_size，查询的个数)\n",
    "    def forward(self, queries, keys, values, valid_lens=None):\n",
    "        d = queries.shape[-1]\n",
    "        # 设置transpose_b=True为了交换keys的最后两个维度\n",
    "        scores = torch.bmm(queries, keys.transpose(1,2)) / math.sqrt(d)\n",
    "        self.attention_weights = masked_softmax(scores, valid_lens)\n",
    "        return torch.bmm(self.dropout(self.attention_weights), values)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "outputs": [],
   "source": [
    "def transpose_qkv(X, num_heads):\n",
    "    \"\"\"为了多注意力头的并行计算而变换形状\"\"\"\n",
    "    # 输入X的形状:(batch_size，查询或者“键－值”对的个数，num_hiddens)\n",
    "    # 输出X的形状:(batch_size，查询或者“键－值”对的个数，num_heads，\n",
    "    # num_hiddens/num_heads)\n",
    "    X = X.reshape(X.shape[0], X.shape[1], num_heads, -1)\n",
    "\n",
    "    # 输出X的形状:(batch_size，num_heads，查询或者“键－值”对的个数,\n",
    "    # num_hiddens/num_heads)\n",
    "    X = X.permute(0, 2, 1, 3)\n",
    "\n",
    "    # 最终输出的形状:(batch_size*num_heads,查询或者“键－值”对的个数,\n",
    "    # num_hiddens/num_heads)\n",
    "    return X.reshape(-1, X.shape[2], X.shape[3])\n",
    "\n",
    "\n",
    "def transpose_output(X, num_heads):\n",
    "    \"\"\"逆转transpose_qkv函数的操作\"\"\"\n",
    "    X = X.reshape(-1, num_heads, X.shape[1], X.shape[2])\n",
    "    X = X.permute(0, 2, 1, 3)\n",
    "    return X.reshape(X.shape[0], X.shape[1], -1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "outputs": [],
   "source": [
    "class MultiHeadAttention(nn.Module):\n",
    "    \"\"\"多头注意力\"\"\"\n",
    "    def __init__(self, key_size, query_size, value_size, num_hiddens,\n",
    "                 num_heads, dropout, bias=False, **kwargs):\n",
    "        super(MultiHeadAttention, self).__init__(**kwargs)\n",
    "        self.num_heads = num_heads\n",
    "        self.attention = DotProductAttention(dropout)\n",
    "        self.W_q = nn.Linear(query_size, num_hiddens, bias=bias)\n",
    "        self.W_k = nn.Linear(key_size, num_hiddens, bias=bias)\n",
    "        self.W_v = nn.Linear(value_size, num_hiddens, bias=bias)\n",
    "        self.W_o = nn.Linear(num_hiddens, num_hiddens, bias=bias)\n",
    "\n",
    "    def forward(self, queries, keys, values, valid_lens):\n",
    "        # queries，keys，values的形状:\n",
    "        # (batch_size，查询或者“键－值”对的个数，num_hiddens)\n",
    "        # valid_lens　的形状:\n",
    "        # (batch_size，)或(batch_size，查询的个数)\n",
    "        # 经过变换后，输出的queries，keys，values　的形状:\n",
    "        # (batch_size*num_heads，查询或者“键－值”对的个数，\n",
    "        # num_hiddens/num_heads)\n",
    "        queries = transpose_qkv(self.W_q(queries), self.num_heads)\n",
    "        keys = transpose_qkv(self.W_k(keys), self.num_heads)\n",
    "        values = transpose_qkv(self.W_v(values), self.num_heads)\n",
    "\n",
    "        if valid_lens is not None:\n",
    "            # 在轴0，将第一项（标量或者矢量）复制num_heads次，\n",
    "            # 然后如此复制第二项，然后诸如此类。\n",
    "            valid_lens = torch.repeat_interleave(\n",
    "                valid_lens, repeats=self.num_heads, dim=0)\n",
    "\n",
    "        # output的形状:(batch_size*num_heads，查询的个数，\n",
    "        # num_hiddens/num_heads)\n",
    "        output = self.attention(queries, keys, values, valid_lens)\n",
    "\n",
    "        # output_concat的形状:(batch_size，查询的个数，num_hiddens)\n",
    "        output_concat = transpose_output(output, self.num_heads)\n",
    "        return self.W_o(output_concat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "MultiHeadAttention(\n",
       "  (attention): DotProductAttention(\n",
       "    (dropout): Dropout(p=0.5, inplace=False)\n",
       "  )\n",
       "  (W_q): Linear(in_features=100, out_features=100, bias=False)\n",
       "  (W_k): Linear(in_features=100, out_features=100, bias=False)\n",
       "  (W_v): Linear(in_features=100, out_features=100, bias=False)\n",
       "  (W_o): Linear(in_features=100, out_features=100, bias=False)\n",
       ")"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "num_hiddens, num_heads = 100, 5\n",
    "attention = MultiHeadAttention(num_hiddens, num_hiddens, num_hiddens, num_hiddens, num_heads, 0.5)\n",
    "attention.eval()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([2, 4, 100])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "batch_size, num_queries, valid_lens = 2, 4, torch.tensor([3, 2])\n",
    "X = torch.ones((batch_size, num_queries, num_hiddens))\n",
    "attention(X, X, X, valid_lens).shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## 比较卷积神经网络、循环神经网络和自注意力\n",
    "\n",
    "![比较卷积神经网络（填充词元被忽略）、循环神经网络和自注意力三种架构](../img/9_attention_mechanisms/cnn-rnn-self-attention.svg)\n",
    "\n",
    "**图1：CNN、RNN和自注意力的架构对比**\n",
    "\n",
    "**关键观察**：\n",
    "- CNN：分层结构，需要多层才能连接远距离位置\n",
    "- RNN：顺序处理，必须逐步传递信息\n",
    "- 自注意力：每个位置直接连接到所有位置\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 三种架构的对比总结\n",
    "\n",
    "| 特性 | CNN | RNN | 自注意力 |\n",
    "|------|-----|-----|---------|\n",
    "| **计算复杂度** | $\\mathcal{O}(knd^2)$ | $\\mathcal{O}(nd^2)$ | $\\mathcal{O}(n^2d)$ |\n",
    "| **顺序操作** | $\\mathcal{O}(1)$ | $\\mathcal{O}(n)$ | $\\mathcal{O}(1)$ |\n",
    "| **最大路径长度** | $\\mathcal{O}(n/k)$ | $\\mathcal{O}(n)$ | $\\mathcal{O}(1)$ |\n",
    "| **并行计算** | ✅ 是 | ❌ 否 | ✅ 是 |\n",
    "| **长距离依赖** | 需要多层 | 需要多步 | 一步到位 |\n",
    "\n",
    "**优势**：\n",
    "- CNN和自注意力：可以并行计算\n",
    "- 自注意力：最大路径长度最短\n",
    "\n",
    "**劣势**：\n",
    "- 自注意力：计算复杂度是序列长度的**二次方**\n",
    "- 对于**很长的序列**，计算会非常慢\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 卷积神经网络（CNN）\n",
    "\n",
    "**计算复杂度**：\n",
    "- 卷积核大小：$k$\n",
    "- 序列长度：$n$\n",
    "- 通道数：$d$\n",
    "- **复杂度**：$\\mathcal{O}(knd^2)$\n",
    "\n",
    "**顺序操作**：\n",
    "- CNN是**分层的**\n",
    "- 每层可以并行计算\n",
    "- **顺序操作数**：$\\mathcal{O}(1)$\n",
    "\n",
    "**最大路径长度**：\n",
    "- 需要多层才能连接远距离位置\n",
    "- **路径长度**：$\\mathcal{O}(n/k)$\n",
    "- 例如：$k=3$的双层CNN，$\\mathbf{x}_1$和$\\mathbf{x}_5$在感受野内\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 循环神经网络（RNN）\n",
    "\n",
    "**计算复杂度**：\n",
    "- 更新隐状态：$d \\times d$矩阵乘法\n",
    "- 单步复杂度：$\\mathcal{O}(d^2)$\n",
    "- 序列长度：$n$\n",
    "- **总复杂度**：$\\mathcal{O}(nd^2)$\n",
    "\n",
    "**顺序操作**：\n",
    "- 必须**逐个**处理序列元素\n",
    "- **顺序操作数**：$\\mathcal{O}(n)$\n",
    "- **无法并行化**\n",
    "\n",
    "**最大路径长度**：\n",
    "- 信息必须逐步传递\n",
    "- **路径长度**：$\\mathcal{O}(n)$\n",
    "- 长距离依赖需要很多步\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 自注意力（Self-Attention）\n",
    "\n",
    "**计算复杂度**：\n",
    "- 查询、键、值：$n \\times d$矩阵\n",
    "- 计算$\\mathbf{Q}\\mathbf{K}^T$：$n \\times d$ × $d \\times n$ = $n \\times n$\n",
    "- 计算$\\mathbf{A}\\mathbf{V}$：$n \\times n$ × $n \\times d$ = $n \\times d$\n",
    "- **复杂度**：$\\mathcal{O}(n^2d)$\n",
    "\n",
    "**顺序操作**：\n",
    "- 所有位置**同时**计算\n",
    "- **顺序操作数**：$\\mathcal{O}(1)$\n",
    "- **完全并行化**\n",
    "\n",
    "**最大路径长度**：\n",
    "- 每个词元**直接连接**到所有其他词元\n",
    "- **路径长度**：$\\mathcal{O}(1)$\n",
    "- 一步即可传递信息\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## 位置编码\n",
    "\n",
    "### 为什么需要位置编码？\n",
    "\n",
    "**问题**：\n",
    "- RNN：**逐个**处理词元，天然包含顺序信息\n",
    "- 自注意力：**并行**计算，**放弃了顺序操作**\n",
    "\n",
    "**例子1：词序影响语义**\n",
    "- \"猫坐在垫子上\" vs \"垫子坐在猫上\"\n",
    "- 词元相同，但位置不同，含义完全不同\n",
    "\n",
    "**例子2：语法依赖**\n",
    "- \"The cat sat on the mat\"\n",
    "- \"cat\"和\"sat\"的位置关系决定了主谓关系\n",
    "- 没有位置信息，无法理解语法结构\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 位置编码的解决方案\n",
    "\n",
    "**核心思想**：\n",
    "- 在输入表示中**添加位置编码**\n",
    "- 注入**绝对位置信息**或**相对位置信息**\n",
    "\n",
    "#### 位置编码的两种方式\n",
    "\n",
    "**1. 可学习的位置编码**：\n",
    "- 作为模型参数学习\n",
    "- 优点：可以适应特定任务\n",
    "- 缺点：需要额外参数，可能过拟合，无法处理训练时未见过的序列长度\n",
    "\n",
    "**2. 固定的位置编码**：\n",
    "- 使用数学函数预先计算\n",
    "- 优点：不需要参数，可以处理任意长度\n",
    "- 缺点：可能不如可学习编码灵活\n",
    "\n",
    "**Transformer的选择**：\n",
    "接下来描述的是基于正弦函数和余弦函数的固定位置编码"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 位置编码的数学形式\n",
    "\n",
    "**输入表示**：\n",
    "- $\\mathbf{X} \\in \\mathbb{R}^{n \\times d}$：$n$个词元的$d$维嵌入\n",
    "\n",
    "**位置嵌入矩阵**：\n",
    "- $\\mathbf{P} \\in \\mathbb{R}^{n \\times d}$：与输入形状相同\n",
    "\n",
    "**输出**：\n",
    "- $\\mathbf{X} + \\mathbf{P}$：词嵌入 + 位置编码\n",
    "\n",
    "**位置编码公式**（第$i$行，第$2j$列和第$2j+1$列）：\n",
    "$$\\begin{aligned} \n",
    "p_{i, 2j} &= \\sin\\left(\\frac{i}{10000^{2j/d}}\\right)\\\\\n",
    "p_{i, 2j+1} &= \\cos\\left(\\frac{i}{10000^{2j/d}}\\right)\n",
    "\\end{aligned}$$\n",
    "\n",
    "**特点**：\n",
    "- 偶数维度用**正弦函数**\n",
    "- 奇数维度用**余弦函数**\n",
    "- 频率随维度变化\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 为什么使用三角函数？\n",
    "\n",
    "**设计动机**：\n",
    "- 需要为每个位置生成**唯一的编码**\n",
    "- 编码应该能够表示**相对位置关系**\n",
    "- 编码应该**可扩展**到任意长度\n",
    "\n",
    "**三角函数的优势**：\n",
    "- 周期性：可以表示相对位置\n",
    "- 连续性：比离散编码更平滑\n",
    "- 可扩展：可以处理任意长度的序列\n",
    "\n",
    "**频率设计**：\n",
    "- 不同维度使用不同频率\n",
    "- 频率随维度**单调递减**\n",
    "- 类似二进制表示的不同比特位\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 相对位置的线性投影\n",
    "\n",
    "**核心思想**：\n",
    "- 对于位置偏移$\\delta$\n",
    "- 位置$i+\\delta$的编码可以通过**线性投影**位置$i$的编码得到\n",
    "\n",
    "**数学形式**：\n",
    "- 令$\\omega_j = 1/10000^{2j/d}$（频率）\n",
    "- 对于位置对$(p_{i, 2j}, p_{i, 2j+1})$\n",
    "- 可以投影到$(p_{i+\\delta, 2j}, p_{i+\\delta, 2j+1})$\n",
    "\n",
    "**投影矩阵**：\n",
    "$$\\begin{bmatrix} \\cos(\\delta \\omega_j) & \\sin(\\delta \\omega_j) \\\\  -\\sin(\\delta \\omega_j) & \\cos(\\delta \\omega_j) \\\\ \\end{bmatrix}$$\n",
    "\n",
    "**关键特点**：\n",
    "- 投影矩阵**不依赖于位置索引$i$**\n",
    "- 只依赖于**偏移量$\\delta$**\n",
    "- 这意味着相对位置关系是**一致的**\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 投影矩阵的推导\n",
    "\n",
    "**投影过程**：\n",
    "$$\\begin{aligned}\n",
    "&\\begin{bmatrix} \\cos(\\delta \\omega_j) & \\sin(\\delta \\omega_j) \\\\  -\\sin(\\delta \\omega_j) & \\cos(\\delta \\omega_j) \\\\ \\end{bmatrix}\n",
    "\\begin{bmatrix} p_{i, 2j} \\\\  p_{i, 2j+1} \\\\ \\end{bmatrix}\\\\\n",
    "=&\\begin{bmatrix} \\cos(\\delta \\omega_j) \\sin(i \\omega_j) + \\sin(\\delta \\omega_j) \\cos(i \\omega_j) \\\\  -\\sin(\\delta \\omega_j) \\sin(i \\omega_j) + \\cos(\\delta \\omega_j) \\cos(i \\omega_j) \\\\ \\end{bmatrix}\\\\\n",
    "=&\\begin{bmatrix} \\sin\\left((i+\\delta) \\omega_j\\right) \\\\  \\cos\\left((i+\\delta) \\omega_j\\right) \\\\ \\end{bmatrix}\\\\\n",
    "=& \\begin{bmatrix} p_{i+\\delta, 2j} \\\\  p_{i+\\delta, 2j+1} \\\\ \\end{bmatrix}\n",
    "\\end{aligned}$$\n",
    "\n",
    "**推导关键**：\n",
    "- 使用三角函数的**和角公式**\n",
    "- $\\sin(a+b) = \\sin(a)\\cos(b) + \\cos(a)\\sin(b)$\n",
    "- $\\cos(a+b) = \\cos(a)\\cos(b) - \\sin(a)\\sin(b)$\n",
    "\n",
    "**意义**：\n",
    "- 模型可以学习相对位置关系\n",
    "- 不需要显式编码所有位置对\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### PositionalEncoding类实现\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "class PositionalEncoding(nn.Module):\n",
    "    \"\"\"位置编码\"\"\"\n",
    "    def __init__(self, num_hiddens, dropout, max_len=1000):\n",
    "        super(PositionalEncoding, self).__init__()\n",
    "        self.dropout = nn.Dropout(dropout)\n",
    "        # 创建一个足够长的P\n",
    "        self.P = torch.zeros((1, max_len, num_hiddens))\n",
    "        X = torch.arange(max_len, dtype=torch.float32).reshape(\n",
    "            -1, 1) / torch.pow(10000, torch.arange(\n",
    "            0, num_hiddens, 2, dtype=torch.float32) / num_hiddens)\n",
    "        self.P[:, :, 0::2] = torch.sin(X)\n",
    "        self.P[:, :, 1::2] = torch.cos(X)\n",
    "\n",
    "    def forward(self, X):\n",
    "        X = X + self.P[:, :X.shape[1], :].to(X.device)\n",
    "        return self.dropout(X)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "**类的组件**：\n",
    "1. `self.dropout`：Dropout层（防止过拟合）\n",
    "2. `self.P`：位置编码矩阵（预计算）\n",
    "\n",
    "**初始化过程**：\n",
    "1. 创建位置索引：`torch.arange(max_len)`\n",
    "2. 计算频率：`10000^(2j/d)`\n",
    "3. 计算正弦和余弦值\n",
    "4. 填充到位置编码矩阵\n",
    "\n",
    "**forward方法**：\n",
    "- 将位置编码添加到输入\n",
    "- 应用Dropout"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 可视化位置编码\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-08-18T07:01:37.253441Z",
     "iopub.status.busy": "2023-08-18T07:01:37.251675Z",
     "iopub.status.idle": "2023-08-18T07:01:37.511460Z",
     "shell.execute_reply": "2023-08-18T07:01:37.510281Z"
    },
    "origin_pos": 19,
    "slideshow": {
     "slide_type": "fragment"
    },
    "tab": [
     "pytorch"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PositionalEncoding(\n",
       "  (dropout): Dropout(p=0, inplace=False)\n",
       ")"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f76e18cb438>"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 864x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "encoding_dim, num_steps = 32, 60\n",
    "pos_encoding = PositionalEncoding(encoding_dim, 0)\n",
    "pos_encoding.eval()\n",
    "X = pos_encoding(torch.zeros((1, num_steps, encoding_dim)))\n",
    "P = pos_encoding.P[:, :X.shape[1], :]\n",
    "fig, ax = plt.subplots(figsize=(12, 5))\n",
    "line_styles = ['-','--',':','-.']\n",
    "for col in range(6,10):\n",
    "    _ = ax.plot(torch.arange(num_steps), P[0, :, col].T, linestyle=line_styles[col-6], label=f\"Col {col}\")\n",
    "_ = ax.set_xlabel('Row (position)')\n",
    "ax.legend()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "在位置嵌入矩阵$\\mathbf{P}$中，[**行代表词元在序列中的位置，列代表位置编码的不同维度**]。\n",
    "- 从上面的例子中可以看到位置嵌入矩阵的第$6$列和第$7$列的频率高于第$8$列和第$9$列。\n",
    "- 第$6$列和第$7$列之间的偏移量（第$8$列和第$9$列相同）是由于正弦函数和余弦函数的交替。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 位置编码热图\n",
    "\n",
    "**热图解读**：\n",
    "- **横轴**：编码维度（Column）\n",
    "- **纵轴**：序列位置（Row）\n",
    "- **颜色深浅**：位置编码值的大小"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "outputs": [],
   "source": [
    "def show_heatmaps(matrices, xlabel, ylabel, titles=None, figsize=(2.5, 2.5),\n",
    "                  cmap='Reds'):\n",
    "    \"\"\"显示矩阵热图\"\"\"\n",
    "    num_rows, num_cols = matrices.shape[0], matrices.shape[1]\n",
    "    fig, axes = plt.subplots(num_rows, num_cols, figsize=figsize,\n",
    "                                 sharex=True, sharey=True, squeeze=False)\n",
    "    for i, (row_axes, row_matrices) in enumerate(zip(axes, matrices)):\n",
    "        for j, (ax, matrix) in enumerate(zip(row_axes, row_matrices)):\n",
    "            pcm = ax.imshow(matrix.detach().numpy(), cmap=cmap)\n",
    "            if i == num_rows - 1:\n",
    "                ax.set_xlabel(xlabel)\n",
    "            if j == 0:\n",
    "                ax.set_ylabel(ylabel)\n",
    "            if titles:\n",
    "                ax.set_title(titles[j])\n",
    "    fig.colorbar(pcm, ax=axes, shrink=0.6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-08-18T07:01:37.528541Z",
     "iopub.status.busy": "2023-08-18T07:01:37.527891Z",
     "iopub.status.idle": "2023-08-18T07:01:37.784120Z",
     "shell.execute_reply": "2023-08-18T07:01:37.782997Z"
    },
    "origin_pos": 26,
    "slideshow": {
     "slide_type": "fragment"
    },
    "tab": [
     "pytorch"
    ]
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 360x504 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "P2 = P[0, :, :].unsqueeze(0).unsqueeze(0)\n",
    "show_heatmaps(P2, xlabel='Column (encoding dimension)',ylabel='Row (position)', figsize=(5, 7), cmap='Blues')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 自注意力的优势与局限\n",
    "\n",
    "**优势**：\n",
    "- ✅ 完全并行计算\n",
    "- ✅ 最大路径长度为1（一步连接所有位置）\n",
    "- ✅ 可以捕获长距离依赖\n",
    "- ✅ 计算简单（矩阵乘法）\n",
    "\n",
    "**局限**：\n",
    "- ❌ 计算复杂度$O(n^2d)$，对长序列慢\n",
    "- ❌ 需要位置编码来补充顺序信息\n",
    "- ❌ 内存消耗大（需要存储$n \\times n$注意力矩阵）\n",
    "\n",
    "**应用场景**：\n",
    "- 中等长度的序列（如句子、段落）\n",
    "- 需要捕获长距离依赖的任务\n",
    "- 可以并行计算的场景"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "幻灯片",
  "hide_input": false,
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  },
  "latex_envs": {
   "LaTeX_envs_menu_present": true,
   "autoclose": true,
   "autocomplete": true,
   "bibliofile": "biblio.bib",
   "cite_by": "apalike",
   "current_citInitial": 1,
   "eqLabelWithNumbers": true,
   "eqNumInitial": 1,
   "hotkeys": {
    "equation": "Ctrl-E",
    "itemize": "Ctrl-I"
   },
   "labels_anchors": false,
   "latex_user_defs": false,
   "report_style_numbering": false,
   "user_envs_cfg": false
  },
  "required_libs": [],
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
